<?php

namespace App\Http\Controllers\Commands;

use App\Consts\ExceptionCodeConst;
use App\Consts\GlobalConst;
use App\Http\Controllers\BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;

/**
 * CommandController
 * Class CommandController
 * @package App\Http\Controllers\Api
 */
class CommandController extends BaseController
{

    /**
     * asynchronous command list
     * @var array
     */
    public $asyncList = ['work'];

    /**
     * Command run
     *
     * @param Request $request
     *      - code     : 76ab92f710cf7210765540cbfeca5e67
     *      - command  : cast:list@--pid:1001||--type:4,5,6
     *      - sync     : false | true
     *      - print    : false | true
     * @return \Illuminate\Http\JsonResponse|mixed
     * @throws \Exception
     */
    public function run(Request $request)
    {
        $code = $request->get('code');
        $sync = $request->get('sync', 'true');
        if ($code != md5(md5(GlobalConst::SECRET_MSG_CENTER))) {
            throw new \Exception(lang('Not Found'), ExceptionCodeConst::ROUTE_NOT_FOUND);
        }
        $res = false;
        $action = $request->get('command', '');
        $async = 'false' === $sync || ('force' !== $sync && in_array($action , $this->asyncList));
        if ($async) {
            // send http response first.
            response()->json($this->buildJson())->send();
        }
        if ($action && $action != 'run') {
            if (!method_exists(static::class, $action)) {
                $request->merge(['command' => $action]);
                $res = $this->command($request);
            } else {
                $res = $this->$action($request);
            }
        }
        return ($async) ? '' : $res;
    }

    /**
     * command execute
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|mixed
     * @throws \Exception
     */
    public function command(Request $request)
    {
        // @example $command :  cast:list@--pid:1001||--type:4,5,6
        $command = $request->get('command', '');
        $print = $request->get('print', 'true');
        $res = false;
        if ($command) {
            $params = [];
            $command = explode('@', $command, 2);
            $param = !empty($command[1]) ? $command[1] : '';
            $command = !empty($command[0]) ? $command[0] : '';
            if (!empty($param)) {
                $param = explode('||', $param);
                foreach ($param as $k => $v) {
                    $list = explode(':', $v, 2);
                    $list[1] = !empty($list[1]) ? $list[1] : '';
                    list($key, $val) = $list;
                    $params[$key] = $val;
                }
            }
            Artisan::call($command, $params);
            $res = Artisan::output() ?: '';
            if ('true' === $print) {
                return "<pre>". PHP_EOL ."{$res}</pre>>";
            }
        }
        return $this->apiReturn($res);
    }

    /**
     * command index
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        $params = $request->all();
        return $this->apiReturn($params, 'command index');
    }

}